﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace CredentialsManager
{
    public static class MainMenuHelper
    {
        public static readonly DependencyProperty HideMainMenuProperty =
        DependencyProperty.RegisterAttached("HideMainMenu",
        typeof(bool), typeof(Window),
        new FrameworkPropertyMetadata(false, OnWindowLoaded));

        public static void SetHideMainMenu(UIElement element, bool value)
        {
            element.SetValue(HideMainMenuProperty, value);
        }

        public static bool GetHideMainMenu(UIElement element)
        {
            return (bool)element.GetValue(HideMainMenuProperty);
        }

        private static void OnWindowLoaded(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
        {
            if (!(bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue))
            {
                if ((bool)e.NewValue)
                {
                    var window = sender as Window;
                    Debug.Assert(window != null);
                    window.Loaded += hostingWindow_Loaded;
                }
            }
        }

        private static void hostingWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var window = sender as Window;

            var menus = FindVisualChildren<Menu>(window);

            foreach (var menu in menus)
            {
                if (menu.IsMainMenu)
                {
                    window.KeyDown += hostingWindow_KeyDown;
                    menu.LostKeyboardFocus += mainMenu_LostKeyboardFocus;
                    menu.Visibility = Visibility.Collapsed;
                    break;
                }
            }

            window.Loaded -= hostingWindow_Loaded;
        }

        private static void hostingWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt || e.SystemKey == Key.F10)
            {
                var window = sender as Window;
                Debug.Assert(window != null);

                foreach (Menu menu in FindVisualChildren<Menu>(window))
                {
                    if (menu.IsMainMenu)
                    {
                        if (menu.Visibility == Visibility.Collapsed)
                        {
                            menu.Visibility = Visibility.Visible;
                        }
                        else
                        {
                            menu.Visibility = Visibility.Collapsed;
                        }

                        break;
                    }
                }
            }
        }

        private static void mainMenu_LostKeyboardFocus(object sender, 
            KeyboardFocusChangedEventArgs e)
        {
            var menu = sender as Menu;

            if (menu.IsMainMenu && !menu.IsKeyboardFocusWithin)
            {
                menu.Visibility = Visibility.Collapsed;
            }
        }

        private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            // thanks to http://stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by-type for this method 

            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }
    }
}
